package com.yxsk.relay.job.admin.aop;

import com.yxsk.relay.job.component.admin.exception.RelayJobAdminException;
import com.yxsk.relay.job.component.admin.exception.RelayJobAdminRuntimeException;
import com.yxsk.relay.job.component.common.protocol.message.base.ResponseCodes;
import com.yxsk.relay.job.component.common.protocol.message.base.ResultResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolationException;

/**
 * Controller层级错误统一处理
 */
@ControllerAdvice
@ResponseBody
@Slf4j
public class RestfulServiceExceptionHandlerAdvice {

    @ExceptionHandler({RelayJobAdminRuntimeException.class})
    public ResultResponse<String> handleAppException(RelayJobAdminRuntimeException e) {
        log.error("", e);
        return ResultResponse.fail(ResponseCodes.SERVICE_INVOKE_ERROR.getCode(), e.getMessage());
    }

    @ExceptionHandler({RelayJobAdminException.class})
    public ResultResponse<String> handleAppException(RelayJobAdminException e) {
        log.error("", e);
        return ResultResponse.fail(ResponseCodes.SERVICE_INVOKE_ERROR.getCode(), e.getMessage());
    }

    @ExceptionHandler({RuntimeException.class})
    public ResultResponse<String> handleRuntimeException(RuntimeException e) {
        log.error("", e);
        return ResultResponse.fail(ResponseCodes.SERVICE_INVOKE_ERROR.getCode(), e.getMessage());
    }

    private String bindingErrMsg(BindingResult bindingResult) {
        StringBuilder stringBuilder = new StringBuilder();
        bindingResult.getFieldErrors().stream().forEach(fieldError -> {
            stringBuilder.append(fieldError.getDefaultMessage()).append(";");
        });

        return stringBuilder.toString();
    }


    @ExceptionHandler({MethodArgumentNotValidException.class})
    public ResultResponse<String> handleValidException(MethodArgumentNotValidException e) {
        String errMsg = bindingErrMsg(e.getBindingResult());

        return ResultResponse.fail(ResponseCodes.PARAMETER_ERROR.getCode(), errMsg);
    }

    @ExceptionHandler({BindException.class})
    public ResultResponse<String> handleValidException(BindException e) {
        String errMsg = bindingErrMsg(e.getBindingResult());

        return ResultResponse.fail(ResponseCodes.PARAMETER_ERROR.getCode(), errMsg);
    }

    @ExceptionHandler({ConstraintViolationException.class})
    public ResultResponse<String> handleValidException(ConstraintViolationException e) {
        StringBuilder stringBuilder = new StringBuilder();

        e.getConstraintViolations().forEach(constraintViolation -> {
            stringBuilder.append(constraintViolation.getMessage()).append(";");
        });

        return ResultResponse.fail(ResponseCodes.PARAMETER_ERROR.getCode(), stringBuilder.toString());
    }

    @ExceptionHandler
    public ResultResponse<String> handleException(Exception e) {
        log.error("系统错误", e);
        return ResultResponse.fail(ResponseCodes.INTERNAL_ERROR.getCode(), e.getMessage());
    }

}
